<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文字转语音实战</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" 
    integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <style>
        body{
            background-color: #141414;
        }
    </style>
</head>
<body class="text-white">
    
    <div class="containter text-center">
        <img src="img/speech.png" alt="" class="mb-5"/>
        <div class="row">
            <div class="col-md-6 mx-auto">
                <form class="mb-5">
                    <div class="form-group">
                        <textarea name="" id="text-input" class="form-control form-control-lg" placeholder="请输入文本内容..."></textarea>
                    </div>
                    <div class="form-group">
                        <label for="pitch">音调</label>
                        <div id="pitch-value" class="badge badge-primary float-right">1</div>
                        <input type="range" name="" id="pitch" class="custom-range" min="0.5" max="2" value="1" step="0.1">
                    </div>
                    <div class="form-group">
                        <label for="rate">音速</label>
                        <div id="rate-value" class="badge badge-primary float-right">1</div>
                        <input type="range" name="" id="rate" class="custom-range" min="0" max="2" value="1" step="0.1">
                    </div>
                   <div class="form-group">
                       <select id="voice-select" class="form-control form-control-lg">
                       </select>
                   </div>
                   <button class="btn btn-light btn-lg btn-block">点击试听</button>
                </form>
                <p class="text-secondary">
                    注意：此应用使用的是Web Speech API,该API是实验中的功能，在某些浏览器版本中可能无法完全使用。
                </p>
            </div>
        </div>       
    </div>

    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" 
    integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" 
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" 
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script>
    //初始化 speechSynthesis API
    const synth = window.speechSynthesis;
    //获取DOM结点
    const body = document.querySelector("body");
    const textForm = document.querySelector("form");
    const textInput = document.querySelector("#text-input");
    const voiceSelect = document.querySelector("#voice-select");
    const rate = document.querySelector("#rate");
    const rateValue = document.querySelector("#rate-value");
    const pitch = document.querySelector("#pitch");
    const pitchValue = document.querySelector("#pitch-value");

    //创建voices arry 并获得下拉语音选项
    let voices = [];

    const getVoices = () =>{
        voices = synth.getVoices();
        //console.log(voices);
        //循环voices数组  并创建option节点插入语音

        voices.forEach(voice => {
            //创建option标签
            const option = document.createElement('option');
            //插入语音名称及语音编码
            option.textContent = voice.name + '(' + voice.lang + ')';
            //设置option属性
            option.setAttribute('data-lang',voice.lang);
            option.setAttribute('data-name',voice.name);
            voiceSelect.appendChild(option);
        });
        
    };

    getVoices();
    if(synth.onvoiceschanged !== undefined){
        synth.onvoiceschanged = getVoices;
    }

    //spaek
    const spaek = () =>{
        //验证是否在说话
        if(synth.speaking){
            console.error('正在说话...');
            return;
        }

        if(textInput.value !== ""){
            //添加背景动画
            body.style.background = "#141414 url(img/wave.gif)";
            body.style.backgroundRepeat = "repeat-x";
            body.style.backgroundSize = "100% 100%";
            body.style.backgroundPositionY = "-80px";
            //获得说话文本
            const speakText = new SpeechSynthesisUtterance(textInput.value);

            //说话结束
            speakText.onend = e =>{
                console.log('说话结束');
                body.style.background = "#141414";
            };

            //发生阻止说出话语的错误就触发
            speakText.onerror = e => {
                console.error('抱歉出错了');
            };

            //选择下拉框中的语音
            const selectVoice = voiceSelect.selectedOptions[0].getAttribute('data-name');
            //遍历voices
            voices.forEach(voice => {
                if(voice.name === selectVoice){
                    speakText.voice = voice;
                }
            });

            //设置音速和音调
            speakText.rate = rate.value;
            speakText.pitch = pitch.value;

            //spesk
            synth.speak(speakText);
        }
    };

    //事件监听

    //form表单文本提交
    textForm.addEventListener('submit', e => {
        e.preventDefault();
        spaek();
        textInput.blur();
    });
    //音速变化
    rate.addEventListener('change',e=>(rateValue.textContent = rate.value));
    //音调变化
    pitch.addEventListener('change',e=>(pitchValue.textContent = pitch.value));

    //下拉框选项切换
    voiceSelect.addEventListener('change',e => spaek());
   
</script>
</body>
</html>